export class Three{
    [k:string]:any;

    vector3(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const x = this.defaultNext("x",node) || 0;
                const y = this.defaultNext("y",node) || 0;
                const z = this.defaultNext("z",node) || 0;

                this.data[index.index] = `new utils.THREE.Vector3(${x},${y},${z})`;
            }

            return this.data[index.index];
        }

        const x = this.defaultNext("x",node);
        const y = this.defaultNext("y",node);
        const z = this.defaultNext("z",node);

        this.data[index] = `new utils.THREE.Vector3(${x||0},${y||0},${z||0})`;

        return this.data[index];
    }

    vector2(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const x = this.defaultNext("x",node) || 0;
                const y = this.defaultNext("y",node) || 0;

                this.data[index.index] = `new utils.THREE.Vector2(${x},${y})`;
            }

            return this.data[index.index];
        }

        const x = this.defaultNext("x",node);
        const y = this.defaultNext("y",node);

        this.data[index] = `new utils.THREE.Vector2(${x||0},${y||0})`;

        return this.data[index];
    }

    scene(index:any,node: {[k:string]:any}){
        this.data[index] = `new utils.THREE.Scene()`;
        return this.data[index];
    }

    perspectiveCamera(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const fov = this.defaultNext("fov",node);
                const aspect = this.defaultNext("aspect",node);
                const near = this.defaultNext("near",node);
                const far = this.defaultNext("far",node);

                this.data[index.index] = `new utils.THREE.PerspectiveCamera(${fov},${aspect},${near},${far})`;
            }

            return this.data[index.index];
        }

        // "fov","aspect","near","far"

        const fov = this.defaultNext("fov",node);
        const aspect = this.defaultNext("aspect",node);
        const near = this.defaultNext("near",node);
        const far = this.defaultNext("far",node);

        this.data[index] = `new utils.THREE.PerspectiveCamera(${fov},${aspect},${near},${far})`;

        return this.data[index];
    }

    webGLRenderer(index:any,node: {[k:string]:any}){
        this.data[index] = `new utils.THREE.WebGLRenderer()`;
        return this.data[index];
    }

    ambientLight(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const color = this.defaultNext("color",node);

                this.data[index.index] = `new utils.THREE.AmbientLight(${color})`;
            }

            return this.data[index.index];
        }

        const color = this.defaultNext("color",node);
        this.data[index] = `new utils.THREE.AmbientLight(${color})`;
        return this.data[index];
    }

    directionalLight(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const color = this.defaultNext("color",node);

                this.data[index.index] = `new utils.THREE.DirectionalLight(${color})`;
            }

            return this.data[index.index];
        }

        const color = this.defaultNext("color",node);
        this.data[index] = `new utils.THREE.DirectionalLight(${color})`;
        return this.data[index];
    }

    clock(index:any,node: {[k:string]:any}){
        this.data[index] = `new utils.THREE.Clock()`;
        return this.data[index];
    }

    color(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const color = this.defaultNext("color",node);

                this.data[index.index] = `new utils.THREE.Color(${color})`;
            }

            return this.data[index.index];
        }

        const color = this.defaultNext("color",node);
        this.data[index] = `new utils.THREE.Color(${color})`;
        return this.data[index];
    }

    axesHelper(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const x = this.defaultNext("x",node) || 5;
                const y = this.defaultNext("y",node) || 5;
                const z = this.defaultNext("z",node) || 5;

                this.data[index.index] = `new utils.THREE.AxesHelper(${x},${y},${z})`;
            }

            return this.data[index.index];
        }

        const x = this.defaultNext("x",node);
        const y = this.defaultNext("y",node);
        const z = this.defaultNext("z",node);

        this.data[index] = `new utils.THREE.AxesHelper(${x||5},${y||5},${z||5})`;

        return this.data[index];
    }

    meshLambertMaterial(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const color = this.defaultNext("color",node);
                const side = this.defaultNext("side",node);
                const map = this.defaultNext("map",node);

                this.data[index.index] = `new utils.THREE.MeshLambertMaterial({color:${color},side:${side},map:${map}})`;
            }

            return this.data[index.index];
        }

        const color = this.defaultNext("color",node);
        const side = this.defaultNext("side",node);
        const map = this.defaultNext("map",node);

        this.data[index] = `new utils.THREE.MeshLambertMaterial({color:${color},side:${side},map:${map}})`;

        return this.data[index];
    }

    meshPhongMaterial(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const color = this.defaultNext("color",node);
                const side = this.defaultNext("side",node);
                const map = this.defaultNext("map",node);

                this.data[index.index] = `new utils.THREE.MeshPhongMaterial({color:${color},side:${side},map:${map}})`;
            }

            return this.data[index.index];
        }

        const color = this.defaultNext("color",node);
        const side = this.defaultNext("side",node);
        const map = this.defaultNext("map",node);

        this.data[index] = `new utils.THREE.MeshPhongMaterial({color:${color},side:${side},map:${map}})`;

        return this.data[index];
    }

    fog(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const color = this.defaultNext("color",node);
                const near = this.defaultNext("near",node);
                const far = this.defaultNext("far",node);

                this.data[index.index] = `new utils.THREE.Fog(${color},${near},${far})`;
            }

            return this.data[index.index];
        }

        // "fov","aspect","near","far"

        const color = this.defaultNext("color",node);
        const near = this.defaultNext("near",node);
        const far = this.defaultNext("far",node);

        this.data[index] = `new utils.THREE.Fog(${color},${near},${far})`;

        return this.data[index];
    }

    mesh(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const geometry = this.defaultNext("geometry",node);
                const material = this.defaultNext("material",node);

                this.data[index.index] = `new utils.THREE.Mesh(${geometry},${material})`;
            }

            return this.data[index.index];
        }

        const geometry = this.defaultNext("geometry",node);
        const material = this.defaultNext("material",node);

        this.data[index] = `new utils.THREE.Mesh(${geometry},${material})`;

        return this.data[index];
    }

    line(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const geometry = this.defaultNext("geometry",node);
                const material = this.defaultNext("material",node);

                this.data[index.index] = `new utils.THREE.Line(${geometry},${material})`;
            }

            return this.data[index.index];
        }

        const geometry = this.defaultNext("geometry",node);
        const material = this.defaultNext("material",node);

        this.data[index] = `new utils.THREE.Line(${geometry},${material})`;

        return this.data[index];
    }

    boxGeometry(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const width = this.defaultNext("width",node);
                const height = this.defaultNext("height",node);
                const depth = this.defaultNext("depth",node);
                const widthSegments = this.defaultNext("widthSegments",node);
                const heightSegments = this.defaultNext("heightSegments",node);
                const depthSegments = this.defaultNext("depthSegments",node);

                this.data[index.index] = `new utils.THREE.BoxGeometry(${width},${height},${depth},${widthSegments},${heightSegments},${depthSegments})`;
            }

            return this.data[index.index];
        }

        // "width","height","depth","widthSegments","heightSegments","depthSegments"
        const width = this.defaultNext("width",node);
        const height = this.defaultNext("height",node);
        const depth = this.defaultNext("depth",node);
        const widthSegments = this.defaultNext("widthSegments",node);
        const heightSegments = this.defaultNext("heightSegments",node);
        const depthSegments = this.defaultNext("depthSegments",node);

        this.data[index] = `new utils.THREE.BoxGeometry(${width},${height},${depth},${widthSegments},${heightSegments},${depthSegments})`;

        return this.data[index];
    }

    addMesh(index:any,node: {[k:string]:any}){

        const target = this.defaultNext("target",node);
        const mesh = this.defaultNext("mesh",node);

        this.data[index] = `${target}.add(${mesh})`;

        const next = this.next(node.next);

        return  `${this.data[index]};${next}`;
    }

    clockAnimationFrame(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                if(index.linkNodeAlias == "delta") return `delta_${node.uuid}`;
                return "";
            }

            return this.data[index.index];
        }

        const nextTimeBody = this.next(node.nextTimeBody);
        const next = this.next(node.next);

        this.data[index] = `utils.animationFrame((delta_${node.uuid})=>{${nextTimeBody}},new utils.THREE.Clock());${next}`;

        return this.data[index];
    }

    aspect(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            return this.data[index.index];
        }
        const target = this.defaultNext("target",node);

        this.data[index] = `utils.aspect(${target})`;

        return this.data[index];
    }

    render(index:any,node: {[k:string]:any}){
        const target = this.defaultNext("target",node);
        const scene = this.defaultNext("scene",node);
        const camera = this.defaultNext("camera",node);
        this.data[index] = `${target}.render(${scene},${camera})`;

        const next = this.next(node.next);
        return `${this.data[index]};${next}`;
    }

    setSize(index:any,node: {[k:string]:any}){

        const target = this.defaultNext("target",node);
        const width = this.defaultNext("width",node);
        const height = this.defaultNext("height",node);

        this.data[index] = `${target}.setSize(${width||0},${height||0})`;

        const next = this.next(node.next);

        return `${this.data[index]};${next}`;
    }

    lookAt(index:any,node: {[k:string]:any}){
        const camera = this.defaultNext("camera",node);
        const x = this.defaultNext("x",node);
        const y = this.defaultNext("y",node);
        const z = this.defaultNext("z",node);
        this.data[index] = `${camera}.lookAt(${x},${y},${z})`;

        const next = this.next(node.next);

        return `${this.data[index]};${next}`;
    }

    setVector2(index:any,node: {[k:string]:any}){

        const target = this.defaultNext("target",node);
        const x = this.defaultNext("x",node);
        const y = this.defaultNext("y",node);

        this.data[index] = `${target}.set(${x||0},${y||0})`;

        const next = this.next(node.next);

        return `${this.data[index]};${next}`;
    }

    setVector3(index:any,node: {[k:string]:any}){

        const target = this.defaultNext("target",node);
        const x = this.defaultNext("x",node);
        const y = this.defaultNext("y",node);
        const z = this.defaultNext("z",node);

        this.data[index] = `${target}.set(${x||0},${y||0},${z||0})`;

        const next = this.next(node.next);

        return `${this.data[index]};${next}`;
    }

    getVector3(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const target = this.defaultNext("target",node);

                this.data[index.index] = target;
            }

            return this.data[index.index] + "."+index.linkNodeAlias;
        }
        return "";
    }

    getVector2(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const target = this.defaultNext("target",node);

                this.data[index.index] = target;
            }

            return this.data[index.index] + "."+index.linkNodeAlias;
        }
        return "";
    }

    setPosition(index:any,node: {[k:string]:any}){

        const target = this.defaultNext("target",node);
        const x = this.defaultNext("x",node);
        const y = this.defaultNext("y",node);
        const z = this.defaultNext("z",node);

        this.data[index] = `${target}.position.set(${x||0},${y||0},${z||0})`;

        const next = this.next(node.next);

        return `${this.data[index]};${next}`;
    }

    setRotation(index:any,node: {[k:string]:any}){

        const target = this.defaultNext("target",node);
        const x = this.defaultNext("x",node);
        const y = this.defaultNext("y",node);
        const z = this.defaultNext("z",node);

        this.data[index] = `${target}.rotation.set(${x||0},${y||0},${z||0})`;

        const next = this.next(node.next);

        return `${this.data[index]};${next}`;
    }

    setScale(index:any,node: {[k:string]:any}){

        const target = this.defaultNext("target",node);
        const x = this.defaultNext("x",node);
        const y = this.defaultNext("y",node);
        const z = this.defaultNext("z",node);

        this.data[index] = `${target}.scale.set(${x||1},${y||1},${z||1})`;

        const next = this.next(node.next);

        return `${this.data[index]};${next}`;
    }

    getPosition(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const target = this.defaultNext("target",node);

                this.data[index.index] = target;
            }

            return this.data[index.index] + ".position."+index.linkNodeAlias;
        }
        return "";
    }

    getRotation(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const target = this.defaultNext("target",node);

                this.data[index.index] = target;
            }

            return this.data[index.index] + ".rotation."+index.linkNodeAlias;
        }
        return "";
    }

    getScale(index:any,node: {[k:string]:any}){
        if(typeof index != "number") {
            if(!this.data[index.index]){
                const target = this.defaultNext("target",node);

                this.data[index.index] = target;
            }

            return this.data[index.index] + ".scale."+index.linkNodeAlias;
        }
        return "";
    }
}